/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.cef.variable.dtgenerator.vardtmGenerate.javageneratecmpcode;

import com.google.common.util.concurrent.ServiceManager;
import com.inspur.edp.bef.component.base.GspComponent;
import com.inspur.edp.cef.designtime.api.operation.CommonOperation;
import com.inspur.edp.cef.variable.dtgenerator.vardtmGenerate.JavaCompCodeNames;
import com.inspur.edp.das.commonmodel.entity.GspCommonModel;
import com.inspur.edp.lcm.metadata.api.IMetadataContent;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.MetadataProjectService;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import javax.swing.Spring;

public abstract class JavaBaseCommonCompCodeGenerator implements JavaIBaseCompCodeGen{
  ///#region 字段
  private String entityNamespace;
  private String apiNamespace;
  private RefCommonService lcmDtService;

  protected CommonOperation operation;
  protected String nameSpace;
  protected String BeName;
  protected String entityClassName;
  //解析型标志

  protected boolean isInterpretation;

  protected abstract String getBaseClassName();
  private String privatePath;
  public final String getPath()
  {
    return privatePath;
  }
  public final void setPath(String value)
  {
    privatePath = value;
  }

  ///#endregion

  private RefCommonService getLcmDtService(){
    if(lcmDtService==null)
      lcmDtService = SpringBeanUtils.getBean(RefCommonService.class);
    return lcmDtService;
}
  ///#region 构造函数
  protected JavaBaseCommonCompCodeGenerator(GspCommonModel gspCommonModel, CommonOperation operation, String nameSpace, String path)
  {
    setPath(path);
    this.operation = operation;
    this.nameSpace = GetNameSpace(nameSpace, gspCommonModel.getCode());
    this.entityClassName = gspCommonModel.getVariables().getGeneratedEntityClassInfo().getClassName();
    //目的是兼容生成variable的文件夹名称误写成Variable
    this.entityNamespace = gspCommonModel.getVariables().getGeneratedEntityClassInfo().getClassNamespace();
    this.apiNamespace = gspCommonModel.getVariables().getGeneratedApiAssemblyInfo().getDefaultNamespace();
    // 解析型
    this.isInterpretation= SpringBeanUtils.getBean(MetadataProjectService.class).isInterpretation(path);
  }

  private String GetNameSpace(String baseNameSpace, String beName)
  {
    String nameSpace = "%1$s.%2$s.%3$s";
    return String.format(nameSpace, baseNameSpace, beName, GetNameSpaceSuffix());
  }


  protected abstract String GetNameSpaceSuffix();
  /**
   获取当前构件名称

   @return
   */
  public final String getCompName()
  {
    if (checkNull(operation.getComponentId()))
    {
      return GetInitializeCompName();
    }
    GspMetadata metadata = getLcmDtService().getRefMetadata(operation.getComponentId());
    if (metadata == null)
    {
      throw new RuntimeException("没有生成构件，无法继续生成代码");
    }

    IMetadataContent content = metadata.getContent();
    String fullClassName = "";
    if (content instanceof GspComponent)
    {
      GspComponent component = (GspComponent)((metadata.getContent() instanceof GspComponent) ? metadata.getContent() : null);
      fullClassName = component.getMethod().getClassName();
    }
    else
    {
      throw new RuntimeException("当前元数据不属于构件元数据");
    }

    String[] sections = fullClassName.split("[.]", -1);
    return sections[sections.length - 1];
  }

  ///#endregion

  /**
   是否执行GenerateCommon()

   */
  public boolean getIsCommonGenerate(){return false;}

  public final String generateExecute()
  {
    StringBuilder result = new StringBuilder();
    ///#region package
    nameSpace = ConvertJavaImportPackage(nameSpace);
    result.append(JavaCompCodeNames.KeywordPackage).append(" ").append(nameSpace).append(";").append(getNewline());

    ///#endregion
    ///#region import
    GenerateImport(result);
    result.append(getNewline());

    ///#endregion
    ///#region ClassStart
    result.append(JavaCompCodeNames.KeywordPublic).append(" ").append(JavaCompCodeNames.KeywordClass).append(" ").append(getCompName()).append(" ").append(JavaCompCodeNames.KeywordExtend).append(" ").append(getBaseClassName()).append(getNewline());
    result.append("{").append(getNewline());

    ///#endregion
    ///#region Field
    JavaGenerateField(result);
    result.append(getNewline());

    ///#endregion
    ///#region Constructor

    JavaGenerateConstructor(result);
    result.append(getNewline());

    ///#endregion
    ///#region execute

    result.append(GetIndentationStr()).append("@").append(JavaCompCodeNames.KeywordOverride).append(getNewline());
    result.append(GetIndentationStr()).append(JavaCompCodeNames.KeywordPublic).append(" ").append(" ").append(JavaCompCodeNames.KeywordVoid).append(" ").append("execute() ");

    result.append(GetIndentationStr()).append("{").append(getNewline());
    result.append(GetIndentationStr()).append("} ").append(getNewline());
    
    ///#endregion
    ///#region ExtendMethod

    JavaGenerateExtendMethod(result);

    ///#endregion
    ///#region ClassEnd
    result.append("}").append(getNewline());
    ///#endregion

    ///#region NameSpaceEnd 命名空间结束
    //result.appendLine("}");
    ///#endregion
    return result.toString();
  }
  ///#region 生成方法

  protected abstract void GenerateExtendUsing(StringBuilder result);
  protected abstract void JavaGenerateConstructor(StringBuilder result);
  protected void JavaGenerateExtendMethod(StringBuilder result)
  {
  }
  protected void JavaGenerateField(StringBuilder result)
  {
  }
  private String ConvertJavaImportPackage(String readPropertyValue_string)
  {
    String[] strArray = readPropertyValue_string.split("[.]", -1);
    String str = "com.";
    int i;

    for (i = 0; i < strArray.length - 1; i++)
    {
      str += strArray[i].toLowerCase() + ".";
    }
    str += strArray[i].toLowerCase();
    return str;
  }

  private String ConvertJavaImportPackageCompatibilityMode(String readPropertyValue_string)
  {
    String[] strArray = readPropertyValue_string.split("[.]", -1);
    String str = "com.";
    int i;

    for (i = 0; i < strArray.length - 2; i++)
    {
      str += strArray[i].toLowerCase() + ".";
    }
    str += strArray[i].toLowerCase();
    str = String.format("%1$s%2$s%3$s", str, ".", strArray[strArray.length - 1]);
    return str;
  }
  private void GenerateImport(StringBuilder result)
  {
    if (!this.isInterpretation)
    {
      //此处不调用ConvertJavaImportPackageCompatibilityMode方法,entityNamespace已经java包名
      entityNamespace = String.format("%1$s%2$s",entityNamespace, ".*");
      result.append(GetImportStr(entityNamespace));
      apiNamespace = String.format("%1$s%2$s",apiNamespace, ".*");
      result.append(GetImportStr(apiNamespace));
    }

    result.append(GetImportStr(JavaCompCodeNames.KeywordIDeterminationContext));
    result.append(GetImportStr(JavaCompCodeNames.KeywordAbstractDetermination));
    result.append(GetImportStr(JavaCompCodeNames.KeywordIChangeDetail));
    result.append(GetImportStr(JavaCompCodeNames.KeywordIVarDeterminationContext));
    result.append(GetImportStr(JavaCompCodeNames.ICefDataNameSpace));
    //JavaGenerateExtendUsing(result);
  }

  ///#endregion
  
  ///#region 通用方法
  protected final String GetImportStr(String value)
  {
    return new StringBuilder(JavaCompCodeNames.KeywordImport).append(" ").append(value).append(";").append(getNewline()).toString();
  }
  protected final String GetUsingStr(String value)
  {
    return new StringBuilder(JavaCompCodeNames.KeywordUsing).append(" ").append(value).append(";").append(getNewline()).toString();
  }

  protected final String getNewline()
  {
    return "\r\n";
  }
  /**
   缩进

   @return
   */
  protected final String GetIndentationStr()
  {
    return "\t";
  }
  /**
   双缩进

   @return
   */
  protected final String GetDoubleIndentationStr()
  {
    return "\t\t";
  }

  ///#endregion

  protected abstract String GetInitializeCompName();

  /**
   2019.3新加，不需要兼容

   @return
   */
  public final String generateCommon()
  {
    return "";
  }

  public  boolean checkNull(Object propValue) {
    if (propValue == null) {
      return true;
    }

    if (propValue.getClass().isAssignableFrom(String.class)) {
      String stringValue = (String) propValue;
      if (stringValue == null || stringValue.isEmpty()) {
        return true;
      }
    }

    return false;
  }
}
